package com.gitee.wsl.data.store.db

import com.gitee.wsl.Lib
import com.gitee.wsl.data.store.AbstractStoreServer
import com.gitee.wsl.data.store.StoreServer
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlin.reflect.KClass


class DBStoreServer (
    private val kvStoreDb: KVStoreDatabase,
    val scope: CoroutineScope = Lib.applicationScope
): AbstractStoreServer() {
    private val kvStoreDao = kvStoreDb.kvStoreDao()

    override fun realRemove(key: String) {
         scope.launch {
            kvStoreDao.delete(key)
        }
    }

    override fun <T : Any> realPut(key: String, value: T) {
        when (value) {
            is String -> runBlocking { kvStoreDao.setValue(key, value) }
            else -> throw IllegalArgumentException(key+":"+value)
        }
    }

    override fun <T : Any> getOrNull(key: String, type: KClass<T>): T? {
        return with(kvStoreDao) {
            val value:Any = when (type) {
                String -> runBlocking { kvStoreDao.loadKV(key)?:"" }
                else -> throw IllegalArgumentException(key)
            }
            return@with value as T
        }
    }

    @OptIn(ExperimentalCoroutinesApi::class)
    override fun isExits(key: String): Boolean {
       val value = runBlocking {
           kvStoreDao.loadKV(key)
       }
       return value!=null
    }

}

fun StoreServer.Companion.db(
    name: String = DB_KVStore_NAME,
    scope: CoroutineScope = Lib.applicationScope
): StoreServer {
    val db = KVStoreDatabase.create(name)
    return DBStoreServer(db, scope = scope)
}
